﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Http;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Extentions;
using TrainingReminderSystem.Model;
using TrainingReminderSystem.Dal;
using System.Threading.Tasks;

namespace TrainingReminderSystem.Bll
{
    /// <summary>
    /// 员工OpenID 逻辑层
    /// </summary>
    public partial class SysEmployeeOpenIDBll : PcLoginedBll
    {
        #region 创建token信息

        /// <summary>
        /// 创建token信息
        /// </summary>
        /// <param name="openID"></param>
        /// <returns></returns>
        public static string CreateWechatToken(SysEmployeeOpenID openID)
        {
            string val =
                $"{openID.ID}{TokenSplit}{openID.OpenID}{TokenSplit}{(int)openID.EnumOpenIDType}{TokenSplit}{(openID.session_Key ?? string.Empty)}{TokenSplit}{(int)SysConfig.EnumRunProject}{TokenSplit}{WechatPcTokenKey}{TokenSplit}{DateTime.Now.ExToLong()}";
            string token = openID.ID + TokenSplit + Extentions.DEncryptHelper.Encrypt(val);
            return token;
        }

        #endregion

        #region 获取token并自动登录,验证token并自动登录

        /// <summary>
        /// 获取token并自动登录,验证token并自动登录
        /// </summary>
        /// <param name="userInfo"></param>
        /// <param name="type"></param>
        /// <param name="wechatToken"></param>
        /// <param name="session_Key">小程序的session_Key</param>
        /// <param name="withCache"></param>
        /// <returns>Message是WechatToken;Result是Token登录信息</returns>
        public static AjaxResult<List<LoginInfo>> GetWechatToken(Senparc.Weixin.Open.OAuthAPIs.OAuthUserInfo userInfo,
            EnumOpenIDType type, string wechatToken, string session_Key, bool withCache = true)
        {
            if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.openid))
            {
                return AjaxResult<List<LoginInfo>>.ErrorResult("没有获取到OPENID值");
            }
            try
            {
                using var db = DbNoFilter;
                SysEmployeeOpenID currentOpenID = db.SysEmployeeOpenID.AsNoTracking()
                    .FirstOrDefault(m => m.OpenID == userInfo.openid && m.EnumOpenIDType == type);
                if (currentOpenID == null)
                {
                    return AjaxResult<List<LoginInfo>>.ErrorResult("没有找到相关OPENID信息");
                }
                SysEmployeeOpenID cacheOpenID = CurrentOpenID;
                if (string.IsNullOrEmpty(session_Key))
                {
                    session_Key = cacheOpenID != null ? cacheOpenID.session_Key : null;
                }
                currentOpenID.session_Key = session_Key;
                if (string.IsNullOrWhiteSpace(wechatToken))
                {
                    wechatToken = cacheOpenID != null ? cacheOpenID.WechatToken : null;
                    if (string.IsNullOrWhiteSpace(wechatToken))
                    {
                        wechatToken = CreateWechatToken(currentOpenID);
                    }
                }
                currentOpenID.WechatToken = wechatToken;
                if (withCache)
                {
                    if (string.IsNullOrWhiteSpace(WechatToken))
                    {
                        WechatToken = wechatToken;
                    }

                    //设置OpenID
                    SetCurrentOpenID(wechatToken, currentOpenID);
                }

                List<LoginInfo> result = null;
                if (currentOpenID.SysEmployeeID != null)
                {
                    //拉出用户Token
                    int sysEmployeeID = currentOpenID.SysEmployeeID.Value;
                    AjaxResult<List<LoginInfo>> ar =
                        new SysEmployeeBll().LoginBase(m => m.SysEmployeeID == sysEmployeeID, null, Token, db, withCache);
                    if (!ar.Success)
                    {
                        return AjaxResult<List<LoginInfo>>.ErrorResult(ar.Message);
                    }
                    if (ar.Result.Count > 0)
                    {
                        result = ar.Result;
                    }
                }

                var r = AjaxResult<List<LoginInfo>>.SuccessResult(result, wechatToken);
                return r;
            }
            catch (Exception ex)
            {
                ex.ExLogError("GetWechatToken报错");
                return AjaxResult<List<LoginInfo>>.ErrorResult("获取OpenID出错");
            }
        }

        //public static string GetToken()
        //{
        //    var customerOpenID = SysEmployeeOpenID;
        //    if (customerOpenID == null)
        //    {
        //        if (!string.IsNullOrEmpty(ChezhuLoginBll.Token))//执行下验证方法,又怕重复执行,写入了个60秒的缓存
        //        {
        //            string cacheKey = ChezhuLoginBll.Token + "_ValidateCache";
        //            AjaxResult<string> cache = CacheHelper.GetCache(cacheKey) as AjaxResult<string>;
        //            if (cache == null)
        //            {
        //                cache = Validate();
        //                CacheHelper.SetAbsoluteCache(cacheKey, cache, 10);
        //                if (cache.Success)
        //                {
        //                    return cache.Result;
        //                }
        //            }
        //        }

        //        return string.Empty;
        //    }
        //    var userInfo = new Senparc.Weixin.Open.OAuthAPIs.OAuthUserInfo();
        //    userInfo.openid = customerOpenID.OpenID;
        //    var r = GetToken(userInfo, customerOpenID.EnumOpenIDType, ChezhuLoginBll.Token);
        //    return r.Result;
        //}

        /// <summary>
        /// 没有openid,也会返回true
        /// </summary>
        /// <returns></returns>
        public static AjaxResult<List<LoginInfo>> LoginByToken()
        {
            string wechatToken = WechatToken;
            if (string.IsNullOrEmpty(wechatToken))
            {
                return AjaxResult<List<LoginInfo>>.SuccessResult();
            }
            var r = new AjaxResult<List<LoginInfo>>();
            //有token解析他,他有具体是某一个帐号的
            var tempArray = wechatToken.Split(TokenSplit);
            var encrypt = wechatToken.Length > 1 ? tempArray[1] : null;
            if (string.IsNullOrEmpty(encrypt))
            {
                //r.Message = "token格式错误";
                return r;
            }
            string val = DEncryptHelper.Decrypt(encrypt);
            if (string.IsNullOrEmpty(val))
            {
                //r.Message = "token格式错误";
                return r;
            }
            var arr = val.Split(TokenSplit);
            if (arr.Length < 6)
            {
                //r.Message = "token格式错误";
                return r;
            }
            int id = arr[0].ExToInt32();
            if (id <= 0)
            {
                //r.Message = "token格式错误";
                return r;
            }
            if (tempArray[0].ExToInt32() != id)
            {
                //r.Message = "token格式错误";
                return r;
            }
            ////店铺ID
            //int sysStoreID = arr[1].ExToInt32();
            //if (sysStoreID <= 0)
            //{
            //    //r.Message = "token格式错误";
            //    return r;
            //}

            string openID = arr[1];
            EnumOpenIDType type = (EnumOpenIDType)arr[2].ExToInt32();
            DateTime dt = arr[arr.Length - 1].ExToDateTime();
            if (dt.Date < DateTime.Now.AddDays(-3).Date)
            {
                //r.Message = "token过期";
                return r;
            }

            string session_Key = arr[3];
            var userInfo = new Senparc.Weixin.Open.OAuthAPIs.OAuthUserInfo();
            userInfo.openid = openID;
            return GetWechatToken(userInfo, type, wechatToken, session_Key);
        }

        #endregion

        #region 注销登录的操作

        public static void Bind(int id)
        {
            if (CurrentOpenID != null && CurrentOpenID.SysEmployeeID != id)
            {
                using var db = PcLoginedBll.DbNoFilter;
                Bind(id, db);
            }
        }

        /// <summary>
        /// 绑定的操作
        /// </summary>
        /// <param name="id"></param>
        /// <param name="db"></param>
        internal static void Bind(int id, DbEntities db)
        {
            if (CurrentOpenID != null && CurrentOpenID.SysEmployeeID != id)
            {
                string sql =
                    $"update {nameof(SysEmployeeOpenID)} set {nameof(SysEmployeeOpenID.SysEmployeeID)}={id} where {nameof(SysEmployeeOpenID.ID)}={CurrentOpenID.ID}";
                db.Database.ExExecuteSqlCommand(sql);
                CurrentOpenID.SysEmployeeID = id;
                SetCurrentOpenID(WechatToken, CurrentOpenID);
            }
        }

        /// <summary>
        /// 解绑
        /// </summary>
        /// <param name="db"></param>
        /// <exception cref="NotImplementedException"></exception>
        internal static void Unbind(DbEntities db)
        {
            if (CurrentOpenID != null)
            {
                string sql =
                    $"update {nameof(SysEmployeeOpenID)} set {nameof(SysEmployeeOpenID.SysEmployeeID)}=null where {nameof(SysEmployeeOpenID.ID)}={CurrentOpenID.ID}";
                db.Database.ExExecuteSqlCommand(sql);
                CurrentOpenID.SysEmployeeID = null;
                SetCurrentOpenID(WechatToken, CurrentOpenID);
            }
        }

        #endregion
    }
}
